package ntu.metaweb.update;

import java.util.Iterator;

import ntu.metaweb.storage.Comment;
import ntu.metaweb.storage.PagesWithTag;
import ntu.metaweb.storage.WebPage;
import ntu.metaweb.storage.WebPageQuery;
import ntu.p2p.dht.DHTContent;
import ntu.p2p.dht.DHTUpdateApplicator;
import ntu.p2p.dht.messaging.DHTObjectDifference;

public class MetawebUpdateApplicator implements DHTUpdateApplicator {

	@Override
	public DHTContent applyUpdate(DHTContent content,
			DHTObjectDifference difference) {
		if (difference instanceof UpdatePageRating) {
			WebPageQuery webpagequery = (WebPageQuery) content;
			UpdatePageRating newRating = (UpdatePageRating) difference;
			webpagequery.addRating(newRating.rating.getRater(), newRating.rating.getRating());
			return webpagequery;
		} else if (difference instanceof NewComment) {
			WebPage webpage = (WebPage) content;
			NewComment newComment = (NewComment) difference;
			webpage.addComment(newComment.comment);
			return webpage;
		} else if (difference instanceof NewTag) {
			NewTag newTag = (NewTag) difference;
			if (content instanceof WebPageQuery) {
				WebPageQuery webpagequery = (WebPageQuery) content;
				webpagequery.addTag(newTag.tag, newTag.tagger);
				return webpagequery;
			} else {
				PagesWithTag pageswithtag = (PagesWithTag) content;
				pageswithtag.addPage(newTag.url, newTag.tagger, 
						newTag.title, newTag.pageRating);
				return pageswithtag;
			}
		} else if (difference instanceof UpdateTagRating) {
			UpdateTagRating rating = (UpdateTagRating) difference;
			if (content instanceof WebPageQuery) {
				WebPageQuery webpagequery = (WebPageQuery) content;
				webpagequery.updateTagRating(rating.tag, rating.user, rating.up);
				return webpagequery;
			} else {
				PagesWithTag pageswithtag = (PagesWithTag) content;
				pageswithtag.updateTagRating(rating.url, rating.user, rating.up);
				return pageswithtag;
			}
		} else if (difference instanceof UpdatePageTitle) {
			UpdatePageTitle newTitle = (UpdatePageTitle) difference;
			System.out.println("update title");
			if (content instanceof WebPageQuery) {
				WebPageQuery webpagequery = (WebPageQuery) content;
				if (newTitle.url.equals(webpagequery.getURL())) {
					webpagequery.setTitle(newTitle.title);
				} else {
					webpagequery.setLinkTitle(newTitle.url, newTitle.title);
				}
				return webpagequery;
			} else {
				PagesWithTag pageswithtag = (PagesWithTag) content;
				pageswithtag.updateTitle(newTitle.url, newTitle.title);
				return pageswithtag;
			}
		} else if (difference instanceof PageAverageRating) {
			PageAverageRating rating = (PageAverageRating) difference;
			if (content instanceof PagesWithTag) {
				PagesWithTag pageswithtag = (PagesWithTag) content;
				pageswithtag.updatePageRating(rating.url, rating.averageRating);
				return pageswithtag;
			} else if (content instanceof WebPageQuery){
				WebPageQuery webpagequery = (WebPageQuery) content;
				webpagequery.updateLinkedPageRating(rating.url, rating.averageRating);
				return webpagequery;
			}
		} else if (difference instanceof UpdateCommentRating) {
			WebPage webpage = (WebPage) content;
			UpdateCommentRating rating = (UpdateCommentRating) difference;
			
			Iterator<Comment> iter = webpage.getComments();
			while (iter.hasNext()) {
				Comment c = iter.next();
				if (c.getId() == rating.id) {
					c.addRating(rating.rating.getRater(), rating.rating.getRating());
					break;
				}
			}
			return webpage;
		} else if (difference instanceof NewLink) {
			NewLink newlink = (NewLink) difference;
			WebPageQuery webpagequery = (WebPageQuery) content;
			webpagequery.addLink(newlink.from, newlink.to, newlink.user, newlink.note);
			return webpagequery;
		} else if (difference instanceof UpdateLinkRating) {
			WebPageQuery webpagequery = (WebPageQuery) content;
			UpdateLinkRating rating = (UpdateLinkRating) difference;
			webpagequery.rateLink(rating.fromURL, rating.toURL, rating.user, 
					rating.up ? 1 : -1);
			return webpagequery;
		} else if (difference instanceof DeleteTag) {
			DeleteTag tag = (DeleteTag) difference;
			if (content instanceof WebPageQuery) {
				WebPageQuery webpagequery = (WebPageQuery) content;
				webpagequery.deleteRating(tag.tag, tag.tagger);
				return webpagequery;
			} else {
				PagesWithTag pageswithtag = (PagesWithTag) content;
				pageswithtag.deleteTag(tag.url, tag.tagger);
				return pageswithtag;
			}
		} else if (difference instanceof DeleteLink) {
			DeleteLink link = (DeleteLink) difference;
			WebPageQuery webpagequery = (WebPageQuery) content;
			webpagequery.deleteLink(link.from, link.to, link.user);
			return webpagequery;
		}
		return null;
	}

}
